using System;

namespace Neoit.Utils.Extensions
{
    /// <summary>
    /// 时间扩展类
    /// </summary>
    public static class DateTimeExtension
    {
        /* default(DateTime) == new DateTime() == DateTime.MinValue == 01/01/0001 00:00:00
         * 
         */

        #region 时间格式化
        /// <summary>
        /// 日期-默认yyyy/MM/dd
        /// </summary>
        public static string Date(this DateTime time, string format = "yyyy/MM/dd")
        {
            return time.ToString(format);
        }
        /// <summary>
        /// 日期时间-默认yyyy/MM/dd HH:mm:ss
        /// </summary>
        /// <param name="time"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static string DateTime(this DateTime time, string format = "yyyy/MM/dd HH:mm:ss")
        {
            return time.ToString(format);
        }
        #endregion

        #region 获取指定时间
        /// <summary>
        /// 获取明天eg:2088-02-02 00:00:00
        /// </summary>
        public static DateTime NextDay(this DateTime time)
        {
            return time.Date.AddDays(1);
        }
        /// <summary>
        /// 月初：eg:2088-02-01 00:00:00
        /// </summary>
        public static DateTime MonthStart(this DateTime time)
        {
            return time.Date.AddDays(1 - time.Day);
        }
        /// <summary>
        /// 下月初：eg:2088-03-01 00:00:00
        /// </summary>
        public static DateTime NextMonthStart(this DateTime time)
        {
            return time.Date.AddDays(1 - time.Day).AddMonths(1);
        }
        /// <summary>
        /// 获取月末[精确到秒s] 2019-12-31 23:59:59
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static DateTime MonthEndOfSecond(this DateTime time)
        {
            return time.Date.AddDays(1 - time.Day).AddMonths(1).AddSeconds(-1);
        }
        #endregion

        #region 日期范围是否有重合
        /// <summary>
        /// 日期范围是否有重合
        /// </summary>
        /// <param name="leftTime"></param>
        /// <param name="rightTime"></param>
        /// <returns></returns>
        public static bool IsOverlap(this (DateTime start, DateTime end) leftTime, (DateTime start, DateTime end) rightTime)
        {
            var b = rightTime.end >= leftTime.start && rightTime.start <= leftTime.end;
            return b;
        }
        #endregion

        #region 日期范围分割【按月】
        //public static List<DateRange> ChangeToPerMonth(List<DateRange> list, DateRange time)
        //{
        //    var last = list.LastOrDefault();
        //    if ((last != null && last.EndTime < time.EndTime) || list.Count == 0)
        //    {
        //        var tmp = time.StartTime;
        //        if (last != null) tmp = last.EndTime.AddMilliseconds(1);
        //        list.Add(new DateRange { StartTime = tmp, EndTime = tmp.AddDays(1 - tmp.Day).AddMonths(1).AddMilliseconds(-1) });
        //        return ChangeToPerMonth(list, time);
        //    }
        //    else
        //    {
        //        var last2 = list.LastOrDefault();
        //        last2.EndTime = time.EndTime;
        //        return list;
        //    }
        //}
        //public class DateRange
        //{
        //    public DateTime StartTime { get; set; }
        //    public DateTime EndTime { get; set; }
        //}
        #endregion

        #region 获取Timestamp时间戳
        /// <summary>
        /// 获取DateTime 10位时间戳（级别：秒）
        /// </summary>
        public static long UnixTimestampSecond(this DateTime dateTime)
        {
            return (dateTime.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }
        /// <summary>
        /// 获取DateTime 13位时间戳（级别：毫秒）
        /// </summary>
        public static long UnixTimestampMillisecond(this DateTime dateTime)
        {
            return (dateTime.ToUniversalTime().Ticks - 621355968000000000) / 10000;
        }
        #endregion

        #region 过了多久、还有多久
        /// <summary>
        /// 过了多久：1分钟前
        /// </summary>
        /// <param name="startTime"></param>
        /// <param name="maxTimeScale">超过最大时间尺度最大表示值时显示具体时间[yyyy/MM/dd HH:mm:ss]，如最大尺度是"时",则超过24小时的显示具体时间</param>
        /// <returns></returns>
        public static string TimeElapsed(this DateTime startTime, TimeScale maxTimeScale = TimeScale.second)
        {
            TimeSpan timeElapsed = System.DateTime.Now - startTime;
            var elapsedTimeString = startTime.ToString();

            int daysInStartTimeMonth = System.DateTime.DaysInMonth(startTime.Year, startTime.Month);

            if (timeElapsed.TotalSeconds < 0)
            {
                elapsedTimeString = "";
            }
            else if (0 < timeElapsed.TotalSeconds && timeElapsed.TotalSeconds < 1)
            {
                elapsedTimeString = $"刚刚";
            }
            else if (1 <= timeElapsed.TotalSeconds && timeElapsed.TotalSeconds < 60)
            {
                elapsedTimeString = $"{timeElapsed.Seconds}秒前";
            }
            else if (timeElapsed.TotalMinutes < 60 && TimeScale.min <= maxTimeScale)
            {
                elapsedTimeString = $"{timeElapsed.Minutes}分钟前";
            }
            else if (timeElapsed.TotalHours < 24 && TimeScale.hour <= maxTimeScale)
            {
                elapsedTimeString = $"{timeElapsed.Hours}小时前";
            }
            else if (0 < timeElapsed.Days && timeElapsed.Days < daysInStartTimeMonth && TimeScale.day <= maxTimeScale)
            {
                elapsedTimeString = $"{timeElapsed.Days}天前";
            }
            else if (daysInStartTimeMonth <= timeElapsed.Days && timeElapsed.Days < 365 && TimeScale.month <= maxTimeScale)
            {
                var monthValue = System.DateTime.Now.Month - startTime.Month;
                var mothCount = monthValue > 0 ? monthValue : monthValue + 12;
                elapsedTimeString = $"{mothCount}月前";
            }
            else if (365 <= timeElapsed.Days && TimeScale.year <= maxTimeScale)
            {
                elapsedTimeString = $"{System.DateTime.Now.Year - startTime.Year}年前";
            }
            return elapsedTimeString;
        }
        /// <summary>
        /// 还有多久：eg. 1分钟后
        /// </summary>
        /// <param name="endTime"></param>
        /// <param name="maxTimeScale">超过最大时间尺度最大表示值时显示具体时间[yyyy/MM/dd HH:mm:ss]，如最大尺度是"时",则超过24小时的显示具体时间</param>
        /// <param name="nowTime">当前时间，默认 System.DateTime.Now</param>
        /// <param name="expiredDisplay">过期时的描述</param>
        /// <returns></returns>
        public static string TimeHowLong(this DateTime endTime, TimeScale maxTimeScale = TimeScale.second, string expiredDisplay = "过期", DateTime? nowTime = null)
        {
            DateTime now = Convert.ToDateTime(nowTime ?? System.DateTime.Now);
            TimeSpan timeElapsed = endTime - now;
            var elapsedTimeString = endTime.ToString();

            //int daysInStartTimeMonth = System.DateTime.DaysInMonth(now.Year, now.Month);
            var nextMonth= now.AddMonths(1);
            int daysInStartTimeNextMonth = System.DateTime.DaysInMonth(nextMonth.Year, nextMonth.Month);

            if (timeElapsed.TotalSeconds < -1)
            {
                elapsedTimeString = expiredDisplay;
            }
            else if (-1 < timeElapsed.TotalSeconds && timeElapsed.TotalSeconds < 1)
            {
                elapsedTimeString = $"即将";
            }
            else if (1 <= timeElapsed.TotalSeconds && timeElapsed.TotalSeconds < 60)
            {
                elapsedTimeString = $"{timeElapsed.Seconds}秒后";
            }
            else if (timeElapsed.TotalMinutes < 60 && TimeScale.min <= maxTimeScale)
            {
                elapsedTimeString = $"{timeElapsed.Minutes}分钟后";
            }
            else if (timeElapsed.TotalHours < 24 && TimeScale.hour <= maxTimeScale)
            {
                elapsedTimeString = $"{timeElapsed.Hours}小时后";
            }
            else if (0 < timeElapsed.Days && timeElapsed.Days < daysInStartTimeNextMonth && TimeScale.day <= maxTimeScale)
            {
                elapsedTimeString = $"{timeElapsed.Days}天后";
            }
            else if (daysInStartTimeNextMonth <= timeElapsed.Days && timeElapsed.Days < 365 && TimeScale.month <= maxTimeScale)
            {
                var monthValue = endTime.Month - now.Month;
                var mothCount = monthValue > 0 ? monthValue : monthValue + 12;
                elapsedTimeString = $"{mothCount}月后";
            }
            else if (365 <= timeElapsed.Days && TimeScale.year <= maxTimeScale)
            {
                elapsedTimeString = $"{endTime.Year - now.Year}年后";
            }

            return elapsedTimeString;
        }
        #endregion

    }

    /// <summary>
    /// 时间尺度
    /// </summary>
    public enum TimeScale
    {
        /// <summary>
        /// 秒
        /// </summary>
        second,
        /// <summary>
        /// 分
        /// </summary>
        min,
        /// <summary>
        /// 时
        /// </summary>
        hour,
        /// <summary>
        /// 日
        /// </summary>
        day,
        /// <summary>
        /// 月
        /// </summary>
        month,
        /// <summary>
        /// 年
        /// </summary>
        year
    }

}
